package com.minhang.exception;

import com.minhang.utils.result.Result;
import com.minhang.utils.result.ResultCode;
import com.minhang.utils.result.ResultGenerator;
import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException;
import com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;

/**
 * 自定义异常
 *
 * @author rookie
 */
@ControllerAdvice
@Slf4j
public class ProcessException {


    /**
     * 捕获自定义异常
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = MyException.class)
    @ResponseBody
    public Result exceptionHandler(HttpServletRequest req, MyException e) {
        String requestUrl = req.getRequestURI();
        log.error(requestUrl + ";发生业务异常！原因是:", e);
        return ResultGenerator.genFailResult(e.getMessage(), e.getResultCode().code());
    }


    /**
     * 处理空指针的异常
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = NullPointerException.class)
    @ResponseBody
    public Result exceptionHandler(HttpServletRequest req, NullPointerException e) {
        String requestUrl = req.getRequestURI();
        log.error(requestUrl + ";发生空指针异常！原因是:", e);
        return ResultGenerator.genFailResult(ResultCode.NullPOINTER.message(), ResultCode.NullPOINTER);
    }


    /**
     * 参数异常
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = NumberFormatException.class)
    @ResponseBody
    public Result exceptionHandler(HttpServletRequest req, NumberFormatException e) {
        String requestUrl = req.getRequestURI();
        log.error(requestUrl + ";参数异常！原因是:", e);
        return ResultGenerator.genFailResult(ResultCode.NUM_BER_FORMAT.message(), ResultCode.NUM_BER_FORMAT);
    }

    /**
     * 数组索引越界
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = ArrayIndexOutOfBoundsException.class)
    @ResponseBody
    public Result exceptionHandler(HttpServletRequest req, ArrayIndexOutOfBoundsException e) {
        String requestUrl = req.getRequestURI();
        log.error(requestUrl + ";数组下标越界！原因是:", e);
        return ResultGenerator.genFailResult(ResultCode.ArrayIndexOutOfBounds.message(), ResultCode.ArrayIndexOutOfBounds);
    }

    /**
     * 索引越界
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = IndexOutOfBoundsException.class)
    @ResponseBody
    public Result exceptionHandler(HttpServletRequest req, IndexOutOfBoundsException e) {
        String requestUrl = req.getRequestURI();
        log.error(requestUrl + ";索引下标越界！原因是:", e);
        return ResultGenerator.genFailResult(ResultCode.IndexOutOfBounds.message(), ResultCode.IndexOutOfBounds);
    }


    /**
     * 类型不存在
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = TypeNotPresentException.class)
    @ResponseBody
    public Result exceptionHandler(HttpServletRequest req, TypeNotPresentException e) {
        String requestUrl = req.getRequestURI();
        log.error(requestUrl + ";类型不存在！原因是:", e);
        return ResultGenerator.genFailResult(ResultCode.TypeNotPresent.message(), ResultCode.TypeNotPresent);
    }


    /**
     * 虚拟机错误
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = VirtualMachineError.class)
    @ResponseBody
    public Result exceptionHandler(HttpServletRequest req, VirtualMachineError e) {
        String requestUrl = req.getRequestURI();
        log.error(requestUrl + ";虚拟机错误！原因是:", e);
        return ResultGenerator.genFailResult(ResultCode.VirtualMachineError.message(), ResultCode.VirtualMachineError);
    }


    /**
     * 堆栈溢出
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = StackOverflowError.class)
    @ResponseBody
    public Result exceptionHandler(HttpServletRequest req, StackOverflowError e) {
        String requestUrl = req.getRequestURI();
        log.error(requestUrl + ";类型不存在！原因是:", e);
        return ResultGenerator.genFailResult(ResultCode.StackOverflowError.message(), ResultCode.StackOverflowError);
    }


    /**
     * 内存不足
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = OutOfMemoryError.class)
    @ResponseBody
    public Result exceptionHandler(HttpServletRequest req, OutOfMemoryError e) {
        String requestUrl = req.getRequestURI();
        log.error(requestUrl + ";类型不存在！原因是:", e);
        return ResultGenerator.genFailResult(ResultCode.OutOfMemoryError.message(), ResultCode.OutOfMemoryError);
    }

    /**
     * sql异常
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = SqlSessionException.class)
    @ResponseBody
    public Result exceptionHandler(HttpServletRequest req, SqlSessionException e) {
        String requestUrl = req.getRequestURI();
        log.error(requestUrl + ";类型不存在！原因是:", e);
        return ResultGenerator.genFailResult(ResultCode.SqlSessionException.message(), ResultCode.SqlSessionException);
    }

    @ExceptionHandler(value = MySQLSyntaxErrorException.class)
    @ResponseBody
    public Result exceptionHandler(HttpServletRequest req, MySQLSyntaxErrorException e) {
        String requestUrl = req.getRequestURI();
        log.error(requestUrl + ";类型不存在！原因是:", e);
        return ResultGenerator.genFailResult(ResultCode.SqlSessionException.message(), ResultCode.SqlSessionException);
    }



    @ExceptionHandler(value = MySQLIntegrityConstraintViolationException.class)
    @ResponseBody
    public Result exceptionHandler(HttpServletRequest req, MySQLIntegrityConstraintViolationException e) {
        String requestUrl = req.getRequestURI();
        log.error(requestUrl + ";类型不存在！原因是:", e);
        return ResultGenerator.genFailResult(ResultCode.SqlSessionException.message(), ResultCode.SqlSessionException);
    }


}
